﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Text;
using OrganizerLibrary.ConfigFile;
using OrganizerLibrary.Processors;

namespace OrganizerLibrary.Settings
{
    public sealed class OrganizerSettings
    {
        private static volatile OrganizerSettings _instance;
        private static readonly Object SyncRoot = new Object();
        private static Boolean _isFinishedLoading = false;
        private readonly OrganizerConfigSection _organizerConfiguration;

        public ProcessorDictionary ProcessorDictionary;

        private OrganizerSettings()
        {
            _organizerConfiguration = LoadOrganizerConfiguration();
            LoadProcessorDictionary();
            _isFinishedLoading = true;
        }

        private static OrganizerConfigSection LoadOrganizerConfiguration()
        {
            return (OrganizerConfigSection)ConfigurationManager.GetSection(OrganizerConfigSection.OrganizerConfigSectionName);
        }

        private void LoadProcessorDictionary()
        {
            ProcessorDictionary = ProcessorDictionary.Instantiate();
            foreach (FileProcessorConfigElement processorConfig in _organizerConfiguration.FileProcessors)
            {
                FileProcessorConfigElement config = processorConfig;
                ProcessorDictionary.AddProcessor(config.FileExtension, inboundFile => StandardProcessor.Instantiate(inboundFile, new DirectoryInfo(config.TargetDirectory)));
            }
            if (RouteNonMapped)
            {
                ProcessorDictionary.AddProcessor(UnmappedDirectoryConstant, inboundFile => StandardProcessor.Instantiate(inboundFile, new DirectoryInfo(RouteNonMappedDirectory)));
            }
        }

        public static OrganizerSettings Instance
        {
            get
            {
                if (!_isFinishedLoading)
                {
                    lock (SyncRoot)
                    {
                        if (!_isFinishedLoading)
                        {
                            _instance = new OrganizerSettings();
                        }
                    }
                }
                return _instance;
            }
        }

        public static String UnmappedDirectoryConstant = "[UNMAPPED]";

        public String DownloadDirectory
        {
            get { return _organizerConfiguration.DirectoryPath; }
        }

        public String RouteNonMappedDirectory
        {
            get { return _organizerConfiguration.RouteNonMappedDirectory; }
        }

        public Boolean RouteNonMapped
        {
            get { return !String.IsNullOrEmpty(RouteNonMappedDirectory); }
        }

        public Boolean UseRelativePaths
        {
            get { return _organizerConfiguration.UseRelativePaths; }
        }

        public Int32 PollingPeriodInMilliseconds
        {
            get { return _organizerConfiguration.PollingPeriodInMilliseconds; }
        }

        public Int32 NumberOfRetries
        {
            get { return _organizerConfiguration.NumberOfRetries; }
        }

        private static Int32 GetAppSettingInt32(String appSettingName)
        {
            return Int32.Parse(GetAppSetting(appSettingName));
        }

        private static String GetAppSetting(String appSettingName)
        {
            return ConfigurationManager.AppSettings[appSettingName];
        }

        private static String GetConnectionString(String connectionStringName)
        {
            return ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString;
        }
    }
}
